这几天再研究canvas画图,简单的写了一个页面,就是用来框物品的,暂时只是让画四边形。
  • 直接上代码就好了,注释都写的比较全了已经。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style type="text/css">
            .father {
                position: relative;
                -moz-user-select: none;
                margin-left: 8%;
                margin-top: 3%;
            }
    
            .canvas {
                position: absolute;
                z-index: 1;
            }
    
            .canvas_bgp {
                position: absolute;
            }
        </style>
    </head>
    <body>
    <div class="father" onselectstart="return false;">
        <canvas id="canvas" class="canvas" width="800" height="500">当前浏览器不支持canvas,请更换浏览器使用!</canvas>
        <img src="./timg.jpg" class="canvas_bgp" width="800" height="500">
    </div>
    </body>
    </html>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script type="text/javascript">
        let canvas = document.getElementById("canvas"); //获取到canvas元素
        let context = canvas.getContext("2d"); //获取上下文的环境
        let arrOld = []; //记录历史位置,回退的时候用
        let timeId; //去掉第二次点击的影响
        let arr = []; //正在画的图形的位置信息
    
        // 画点
        function drawPoint(cxt, x, y, w, borderWidth, borderColor, fillColor) {
            cxt.beginPath();
            cxt.moveTo(x - w, y - w);
            cxt.lineTo(x + w, y - w);
            cxt.lineTo(x + w, y + w);
            cxt.lineTo(x - w, y + w);
            cxt.lineWidth = borderWidth;
            cxt.strokeStyle = borderColor;
            cxt.fillStyle = fillColor;
            cxt.closePath();
            cxt.fill();
            cxt.stroke();
        }
    
        // 画多边形
        function drawPolygon(cxt, dbl, borderWidth, borderColor, fillColor, t) {
            for (let i = 0; i < dbl.length; i++) {
                drawPoint(cxt, dbl[i].x, dbl[i].y, 2, 1, 'black', 'skyblue');
            }
            cxt.moveTo(dbl[0].x, dbl[0].y);
            for (let i = 1; i < dbl.length; i++) {
                cxt.lineTo(dbl[i].x, dbl[i].y);
            }
            if (t) {
                cxt.closePath();
                cxt.fillStyle = fillColor;
                cxt.fill();
            }
            cxt.lineWidth = borderWidth;
            cxt.strokeStyle = borderColor;
            cxt.stroke();
        }
    
        // canvas.ondblclick = function () {
        function generate() {
            // clearTimeout(timeId);//清除第二次的点击事件
            // 需要画三个点以上才能闭合
            if (arr.length > 2) {
                // 再次添加起点,这样回退的时候就不会出现一下消失两个线条的情况
                arr.push({x: arr[0].x, y: arr[0].y});
                drawPolygon(context, arr, 3, 'green', "rgba(0, 0, 0, 0)", false);
                // 将arr存起来
                arrOld.push(arr);
                // 在列表中添加一条信息
                addition(arr);
                // 这里执行完成闭合之后,清空坐标数组,便于另外新建
                arr = [];
                // 此处需要获取所有点的坐标
                console.log(arrOld);
            } else {
                alert("无可闭合的图形")
            }
        }
    
        //单击确定点的位置
        canvas.onclick = function (e) {
            clearTimeout(timeId);//清除第二次的点击事件
            timeId = setTimeout(function () {
                let x = e.offsetX;
                let y = e.offsetY;
                arr.push({x: x, y: y});
                drawPolygon(context, arr, 3, 'green');
                // 现在点击四个点就闭合图形,因为只要求是四边形
                if(arr.length == 4){
                    generate();
                }
            }, 250)
        };
    
        //回退操作
        canvas.ondblclick = function () {
            clearTimeout(timeId);//清除第二次的点击事件
        // function regression() {
            if(arr.length == 0 && arrOld.length == 0){
                alert("无法回退");
                return;
            }
            if (arr.length > 0) {
                // 删除在画的
                arr = arr.slice(0, arr.length - 1);
            } else {
                // 删除已经画好的
                if (arrOld.length > 0) {
                    // 拿出历史数组中最后一个
                    arr = arrOld[arrOld.length - 1].slice(0, arr.length - 1);
                    // 删除历史中最后一个
                    arrOld = arrOld.slice(0, arrOld.length - 1);
                }
            }
            //清空画板,重画
            clean();
        };
    
        //显示线条
        canvas.onmousemove = function() {
            //清空画板,重画
            clean();
            //划线不画点
            if(arr.length > 0 && arr.length < 4){
                let bbox = canvas.getBoundingClientRect();
                let x =  event.clientX - bbox.left * (canvas.width/bbox.width);
                let y = event.clientY - bbox.top * (canvas.height/bbox.height);
                context.moveTo(arr[arr.length-1].x, arr[arr.length-1].y);
                context.lineTo(x, y);
                context.lineWidth = 3;
                context.strokeStyle = 'green';
                context.stroke();
            }
        };
    
        // 清空画板,重画
        function clean() {
            //清空画板,重画
            context.clearRect(0, 0, 800, 500);
            for (let i = 0; i < arrOld.length; i++) {
                drawPolygon(context, arrOld[i], 3, 'green', "rgba(0, 0, 0, 0)", false);
            }
            if (arr.length > 0) {
                drawPolygon(context, arr, 3, 'green');
            }
        }
    </script>
    
  • 心得就是canvas就是反复的清除后再重新画,因为是由点画线,所以我在最后图形完成的时候讨巧多存了一个起点,这样在回退操作的时候就不会出现去掉一个点从而少了两根线的问题。

周兆东
107 声望21 粉丝

一个java小白的成长之路。。。